﻿using System;
using System.Collections.Generic;
using System.Text;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;

namespace GISCommon.Business
{
    public class GeometryTools
    {
        private ESRI.ArcGIS.Controls.AxMapControl pMapControl = null;

        public ESRI.ArcGIS.Controls.AxMapControl MapControl
        {
            get { return pMapControl; }
            set { pMapControl = value; }
        }

        #region 构造函数

        /// <summary>
        /// 描述：带地图控件参数的构造函数

        /// </summary>
        /// <param name="inMapControl">地图控件</param>
        public GeometryTools(ESRI.ArcGIS.Controls.AxMapControl inMapControl)
        {
            try
            {
                SysCommon.Global.mainLog.Debug("开始调用GeometryTools类的构造函数！");
                pMapControl = inMapControl;
                SysCommon.Global.mainLog.Debug("调用GeometryTools类的构造函数完成！");
            }
            catch(Exception ex)
            {
                SysCommon.Global.mainLog.Error("调用GeometryTools类出错！",ex);
            }
        }

        public GeometryTools()
        {
        }
        #endregion

        #region 闪烁显示
        /// <summary>
        /// 描述：闪烁显示

        /// </summary>
        /// <param name="inGeometry">Geometry对象</param>
        /// <param name="inMapControl">地图控件</param>
        public void FlashGeometry(ESRI.ArcGIS.Geometry.IGeometry inGeometry,ESRI.ArcGIS.Controls.AxMapControl inMapControl)
        {
            try
            {
                SysCommon.Global.mainLog.Debug("开始调用FlashGeometry函数！");
                ESRI.ArcGIS.Geometry.IGeometry pGeometry = inGeometry;
                if (pGeometry != null && inMapControl != null)
                {
                    ESRI.ArcGIS.Geometry.esriGeometryType GeoType = pGeometry.GeometryType;
                    ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp = null;
                    double ration = 0.00000001*inMapControl.Map.MapScale;

                    switch(GeoType)
                    {
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
                            pTopOp=(ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryLine:
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint:
                            ESRI.ArcGIS.Geometry.IPointCollection pPtColl =
                                (ESRI.ArcGIS.Geometry.IPointCollection) pGeometry;
                            ESRI.ArcGIS.Geometry.IPointCollection pPC = new ESRI.ArcGIS.Geometry.PolygonClass();
                            pPC.AddPointCollection(pPtColl);
                            ESRI.ArcGIS.Geometry.IPolygon pPG = (ESRI.ArcGIS.Geometry.IPolygon)pPC; //new ESRI.ArcGIS.Geometry.PolygonClass();
                            pGeometry = pPG;
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch:
                            ESRI.ArcGIS.Geometry.IGeometryCollection pGeoColl =(ESRI.ArcGIS.Geometry.IGeometryCollection)pGeometry;
                            ESRI.ArcGIS.Geometry.IPolyline pPL = (ESRI.ArcGIS.Geometry.IPolyline)pGeoColl.get_Geometry(0);
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator) pPL;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryNull:
                            break;
                    }

                    inMapControl.FlashShape(pGeometry);
                }
                else
                {
                    SysCommon.Global.mainLog.Debug("您输入的Geometry或者MapControl为空！");
                }
                SysCommon.Global.mainLog.Debug("调用FlashGeometry函数结束！");
            }
            catch (Exception ex)
            {
                SysCommon.Global.mainLog.Error("调用FlashGeometry函数出错！",ex);
            }
        }

        /// <summary>
        /// 描述：闪烁显示

        /// </summary>
        /// <param name="inGeometry">Geometry对象</param>
        public void FlashGeometry(ESRI.ArcGIS.Geometry.IGeometry inGeometry)
        {
            SysCommon.Global.mainLog.Debug("开始调用FlashGeometry函数！");
            try
            {
                ESRI.ArcGIS.Geometry.IGeometry pGeometry = inGeometry;
                if (pGeometry != null && pMapControl != null)
                {
                    ESRI.ArcGIS.Geometry.esriGeometryType GeoType = pGeometry.GeometryType;
                    ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp = null;
                    double ration = 0.00000001 * pMapControl.Map.MapScale;

                    switch (GeoType)
                    {
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryLine:
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint:
                            ESRI.ArcGIS.Geometry.IPointCollection pPtColl =
                                (ESRI.ArcGIS.Geometry.IPointCollection)pGeometry;

                            if (pPtColl.PointCount <= 1)
                            {
                                ESRI.ArcGIS.Geometry.IPoint pt = pPtColl.get_Point(0);
                                pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pt;
                                pGeometry = pTopOp.Buffer(ration);
                                break;
                            }

                            ESRI.ArcGIS.Geometry.IPointCollection pPC = new ESRI.ArcGIS.Geometry.PolygonClass();
                            pPC.AddPointCollection(pPtColl);
                            ESRI.ArcGIS.Geometry.IPolygon pPG = (ESRI.ArcGIS.Geometry.IPolygon)pPC; //new ESRI.ArcGIS.Geometry.PolygonClass();
                            pGeometry = pPG;
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch:
                            ESRI.ArcGIS.Geometry.IGeometryCollection pGeoColl = (ESRI.ArcGIS.Geometry.IGeometryCollection)pGeometry;
                            ESRI.ArcGIS.Geometry.IPolyline pPL = (ESRI.ArcGIS.Geometry.IPolyline)pGeoColl.get_Geometry(0);
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pPL;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryNull:
                            break;
                    }

                    pMapControl.FlashShape(pGeometry);
                }
                else
                {
                    SysCommon.Global.mainLog.Debug("输入的Geometry或者MapControl为空！");
                }
                SysCommon.Global.mainLog.Debug("调用FlashGeometry函数结束！");
            }
            catch (Exception ex)
            {
                SysCommon.Global.mainLog.Error("FlashGeometry出错！",ex);
            }
        }

        /// <summary>
        /// 描述：闪烁显示


        /// </summary>
        /// <param name="inGeometry">Geometry对象</param>
        public void FlashGeometry(ESRI.ArcGIS.Geometry.IGeometry inGeometry,bool IsForCar)
        {
            SysCommon.Global.mainLog.Debug("开始调用FlashGeometry函数！");
            try
            {
                
                ESRI.ArcGIS.Geometry.IGeometry pGeometry = inGeometry;
                if (pGeometry != null && pMapControl != null)
                {
                    ESRI.ArcGIS.Geometry.esriGeometryType GeoType = pGeometry.GeometryType;
                    ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp = null;

                    double ration = 0.00000001 * pMapControl.Map.MapScale;

                    if (IsForCar)
                    {
                        ration = ration*4;
                    }

                    switch (GeoType)
                    {
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryLine:
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint:
                            ESRI.ArcGIS.Geometry.IPointCollection pPtColl =
                                (ESRI.ArcGIS.Geometry.IPointCollection)pGeometry;

                            if(pPtColl.PointCount<=1)
                            {
                                ESRI.ArcGIS.Geometry.IPoint pt = pPtColl.get_Point(0);
                                pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pt;
                                pGeometry = pTopOp.Buffer(ration);
                                break;
                            }
                            ESRI.ArcGIS.Geometry.IPointCollection pPC = new ESRI.ArcGIS.Geometry.PolygonClass();
                            pPC.AddPointCollection(pPtColl);
                            ESRI.ArcGIS.Geometry.IPolygon pPG = (ESRI.ArcGIS.Geometry.IPolygon)pPC; //new ESRI.ArcGIS.Geometry.PolygonClass();
                            pGeometry = pPG;
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch:
                            ESRI.ArcGIS.Geometry.IGeometryCollection pGeoColl = (ESRI.ArcGIS.Geometry.IGeometryCollection)pGeometry;
                            ESRI.ArcGIS.Geometry.IPolyline pPL = (ESRI.ArcGIS.Geometry.IPolyline)pGeoColl.get_Geometry(0);
                            pTopOp = (ESRI.ArcGIS.Geometry.ITopologicalOperator)pPL;
                            pGeometry = pTopOp.Buffer(ration);
                            break;
                        case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryNull:
                            break;
                    }

                    pMapControl.FlashShape(pGeometry);
                }
                else
                {
                    SysCommon.Global.mainLog.Debug("输入的Geometry或者MapControl为空！");
                }
                SysCommon.Global.mainLog.Debug("调用FlashGeometry函数结束！");
            }
            catch (Exception ex)
            {
                SysCommon.Global.mainLog.Error("FlashGeometry出错！", ex);
            }
        }
        #endregion

        #region 缩放定位

        /// <summary>
        /// 描述：缩放定位

        /// </summary>
        /// <param name="inGeometry">Geometry对象</param>
        /// <param name="inMapControl">地图控件</param>
        public void ZoomToGeometry(ESRI.ArcGIS.Geometry.IGeometry inGeometry,ESRI.ArcGIS.Controls.AxMapControl inMapControl)
        {
            try
            {
                SysCommon.Global.mainLog.Debug("开始调用ZoomToGeometry函数！");
                ESRI.ArcGIS.Geometry.IGeometry pGeometry = inGeometry;
                ESRI.ArcGIS.Geometry.esriGeometryType GeoType = pGeometry.GeometryType;

                if(GeoType==ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint)
                {
                    ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp =
                        (ESRI.ArcGIS.Geometry.ITopologicalOperator) pGeometry;
                    pGeometry = pTopOp.Buffer(0.00001);
                }
                if (GeoType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint)
                {
                    ESRI.ArcGIS.Geometry.IPointCollection multipoint = (ESRI.ArcGIS.Geometry.IPointCollection)inGeometry;
                    if (multipoint.PointCount == 1)
                    {
                        ESRI.ArcGIS.Geometry.IPoint point = multipoint.get_Point(0);
                        ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp =
                            (ESRI.ArcGIS.Geometry.ITopologicalOperator)point;
                        pGeometry = pTopOp.Buffer(0.00001);
                    }
                }

                ESRI.ArcGIS.Geometry.IEnvelope pEnvelope = pGeometry.Envelope;
                pEnvelope.Expand(1.2,1.2,true);
                inMapControl.ActiveView.ScreenDisplay.DisplayTransformation.Bounds = pEnvelope;

                //inMapControl.ActiveView.Refresh();

                SysCommon.Global.mainLog.Debug("调用ZoomToGeometry函数结束！");
            }
            catch(Exception ex)
            {
                SysCommon.Global.mainLog.Error("ZoomToGeometry出错！",ex );
            }
        }

        /// <summary>
        /// 描述：缩放显示

        /// </summary>
        /// <param name="inGeometry">Geometry对象</param>
        public void ZoomToGeometry(ESRI.ArcGIS.Geometry.IGeometry inGeometry)
        {
            try
            {
                SysCommon.Global.mainLog.Debug("开始调用ZoomToGeometry函数！");
                if(pMapControl==null)
                {
                    SysCommon.Global.mainLog.Debug("MapControl控件为空，调用ZoomToGeometry函数结束！");
                    return;
                }

                ESRI.ArcGIS.Geometry.IGeometry pGeometry = inGeometry;
                ESRI.ArcGIS.Geometry.esriGeometryType GeoType = pGeometry.GeometryType;
                double ration = 0.0000001 * pMapControl.Map.MapScale;

                if (GeoType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint)
                {
                    ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp =
                        (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                    ration = 0.0000001*50000;
                    pGeometry = pTopOp.Buffer(ration);
                }
                if(GeoType==ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint)
                {
                    ESRI.ArcGIS.Geometry.IPointCollection multipoint = (ESRI.ArcGIS.Geometry.IPointCollection)inGeometry;
                    if(multipoint.PointCount==1)
                    {
                        ESRI.ArcGIS.Geometry.IPoint point = multipoint.get_Point(0);
                        ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp =
                            (ESRI.ArcGIS.Geometry.ITopologicalOperator) point;
                        ration = 0.0000001 * 50000;
                        pGeometry = pTopOp.Buffer(ration);
                        //pGeometry = pTopOp.Buffer(0.002);
                    }
                }

                ESRI.ArcGIS.Geometry.IEnvelope pEnvelope = pGeometry.Envelope;
                //pEnvelope.Expand(1,1, true);
    
                pMapControl.ActiveView.ScreenDisplay.DisplayTransformation.Bounds = pEnvelope;
               
                //pMapControl.ActiveView.Refresh();
                SysCommon.Global.mainLog.Debug("调用ZoomToGeometry函数结束！");
            }
            catch (Exception ex)
            {
                SysCommon.Global.mainLog.Debug("ZoomToGeometry出错！",ex);
            }

        }
        #endregion
        #region 定位指定车辆
        public void ZoomToCarGeometry(ESRI.ArcGIS.Geometry.IGeometry inGeometry)
        {
            try
            {
                SysCommon.Global.mainLog.Debug("开始调用ZoomToGeometry函数！");
                if (pMapControl == null)
                {
                    SysCommon.Global.mainLog.Debug("MapControl控件为空，调用ZoomToGeometry函数结束！");
                    return;
                }

                ESRI.ArcGIS.Geometry.IGeometry pGeometry = inGeometry;
                ESRI.ArcGIS.Geometry.esriGeometryType GeoType = pGeometry.GeometryType;
                double ration = 0.0000001 * pMapControl.Map.MapScale;

                if (GeoType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint)
                {
                    ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp =
                        (ESRI.ArcGIS.Geometry.ITopologicalOperator)pGeometry;
                    ration = 0.0000001 * 50000;
                    pGeometry = pTopOp.Buffer(ration);
                }
                if (GeoType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultipoint)
                {
                    ESRI.ArcGIS.Geometry.IPointCollection multipoint = (ESRI.ArcGIS.Geometry.IPointCollection)inGeometry;
                    if (multipoint.PointCount == 1)
                    {
                        ESRI.ArcGIS.Geometry.IPoint point = multipoint.get_Point(0);
                        ESRI.ArcGIS.Geometry.ITopologicalOperator pTopOp =
                            (ESRI.ArcGIS.Geometry.ITopologicalOperator)point;
                        ration = 0.0000001 * 50000;
                        pGeometry = pTopOp.Buffer(ration);
                        //pGeometry = pTopOp.Buffer(0.002);
                    }
                }
                 
                ESRI.ArcGIS.Geometry.IEnvelope pEnvelope = pGeometry.Envelope;
                pEnvelope.Expand(1.2, 1.2, true);
               
                pMapControl.ActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds= pEnvelope;
                
             //  pMapControl.ActiveView.Refresh();
                SysCommon.Global.mainLog.Debug("调用ZoomToGeometry函数结束！");
            }
            catch (Exception ex)
            {
                SysCommon.Global.mainLog.Debug("ZoomToGeometry出错！", ex);
            }

        }
        #endregion
        #region 画线
        public void DrawPolyline(ESRI.ArcGIS.Geometry.IPolyline pPolyline,ESRI.ArcGIS.Controls.AxMapControl inMapControl)
        {
            try
            {
                SysCommon.Global.mainLog.Debug("开始调用DrawPolyline函数！");
                //线条颜色
                IRgbColor pColor = new RgbColorClass();
                pColor.Red = 255;
                pColor.Green = 109;
                pColor.Blue = 109;

                //线条样式
                ISimpleLineSymbol pSymbol = new SimpleLineSymbolClass();
                pSymbol.Color = pColor;
                pSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
                pSymbol.Width = 2;

                //创建线条对象
                ILineElement pLineElement = new LineElementClass();
                pLineElement.Symbol = pSymbol;

                //创建新元素

                IElement pElement = (IElement)pLineElement;
                pElement.Geometry = pPolyline;

                //画线
                inMapControl.ActiveView.GraphicsContainer.AddElement(pElement,0);

                //刷新
                inMapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics,pElement,pPolyline.Envelope);
                SysCommon.Global.mainLog.Debug("调用DrawPolyline函数结束！");
            }
            catch(Exception ex)
            {
                SysCommon.Global.mainLog.Error("调用能够DrawPolyline函数出错！",ex);
            }
        }
        #endregion

        private void AddTextBackground(string text,ESRI.ArcGIS.Geometry.IPoint point, ESRI.ArcGIS.Controls.AxMapControl inMapControl)
        {
            ESRI.ArcGIS.Geometry.IPoint pPoint = point;// new ESRI.ArcGIS.Geometry.PointClass();
            //pPoint.PutCoords(ety.LONGITUDE, ety.LATITUDE);
            ITextElement pTextElement = (ITextElement)new TextElementClass();
            pTextElement.Text = text;// ety.CARPLATE;

            IRgbColor pColor = (IRgbColor)new RgbColorClass();
            pColor.Red = 255;
            pColor.Green = 230;

            //dim and set balloon callout object
            IBalloonCallout pBalloonCallout = (IBalloonCallout)new BalloonCalloutClass();

            //dim and set fill symbol for callout element
            IFillSymbol pFillSymbol = (IFillSymbol)new SimpleFillSymbolClass();

            //set fill color
            pFillSymbol.Color = pColor;

            //dim and set line symbol for callout outline
            ILineSymbol pLineSymbol = (ILineSymbol)new SimpleLineSymbolClass();

            //reset color
            pColor.Red = 0;
            pColor.Blue = 255;

            //set outline color
            pLineSymbol.Color = pColor;

            //set fill symbol outline property to line symbol
            pFillSymbol.Outline = pLineSymbol;

            //set balloon callout object properties
            pBalloonCallout.Symbol = pFillSymbol;
            pBalloonCallout.AnchorPoint = pPoint;
            pBalloonCallout.LeaderTolerance = 0;
            pBalloonCallout.Style = (esriBalloonCalloutStyle)1;

            //now set properties to complete element
            //dim and set text background object
            ITextBackground pTextBackground = (ITextBackground)pBalloonCallout;

            //dim and set formatted text symbol for 
            //specialized callout element
            IFormattedTextSymbol pFormattedTextSymbol = (IFormattedTextSymbol)new TextSymbolClass();

            //set label symbol properties
            pFormattedTextSymbol.Background = pTextBackground;
            pFormattedTextSymbol.Size = 12;

            ISimpleTextSymbol pTextSymbol = (ISimpleTextSymbol)pFormattedTextSymbol;
            pTextSymbol.YOffset = 10;
            pTextSymbol.XOffset = 40;
            pTextSymbol.Angle = 45;
            pColor.Blue = 255;
            pColor.Green = 0;
            pColor.Red = 108;
            pTextSymbol.Color = pColor;

            //set text element custom symbol
            pTextElement.Symbol = pTextSymbol;// pFormattedTextSymbol;

            //dim and set element properties object
            IElementProperties pElementPro = (IElementProperties)pTextElement;

            //set element properties
            pElementPro.Type = "Jeffco Callout";

            //dim and set Element to be added to map
            IElement pElement = (IElement)pElementPro;

            //dim and set Geometry
            ESRI.ArcGIS.Geometry.IGeometry pGeometry = (ESRI.ArcGIS.Geometry.IGeometry)pPoint;

            //add graphic to map
            IMap pMap = pMapControl.ActiveView.FocusMap;
            IGraphicsContainer pGraCon = (IGraphicsContainer)pMap;
            pElement.Geometry = pGeometry;

            pGraCon.AddElement(pElement, 0);
            esriViewDrawPhase p = esriViewDrawPhase.esriViewGraphics;
            inMapControl.ActiveView.PartialRefresh(p, pElement, null);
        }

        private void AddTextBackground(string text,ESRI.ArcGIS.Geometry.IPoint point)
        {
            ESRI.ArcGIS.Geometry.IPoint pPoint = point;

            ITextElement pTextElement = (ITextElement)new TextElementClass();
            pTextElement.Text = text;

            IRgbColor pColor = (IRgbColor)new RgbColorClass();
            pColor.Red = 255;
            pColor.Green = 230;

            //dim and set balloon callout object
            IBalloonCallout pBalloonCallout = (IBalloonCallout)new BalloonCalloutClass();

            //dim and set fill symbol for callout element
            IFillSymbol pFillSymbol = (IFillSymbol)new SimpleFillSymbolClass();

            //set fill color
            pFillSymbol.Color = pColor;

            //dim and set line symbol for callout outline
            ILineSymbol pLineSymbol = (ILineSymbol)new SimpleLineSymbolClass();

            //reset color
            pColor.Red = 0;
            pColor.Blue = 255;

            //set outline color
            pLineSymbol.Color = pColor;

            //set fill symbol outline property to line symbol
            pFillSymbol.Outline = pLineSymbol;

            //set balloon callout object properties
            pBalloonCallout.Symbol = pFillSymbol;
            pBalloonCallout.AnchorPoint = pPoint;
            pBalloonCallout.LeaderTolerance = 0;
            pBalloonCallout.Style = (esriBalloonCalloutStyle)1;

            //now set properties to complete element
            //dim and set text background object
            ITextBackground pTextBackground = (ITextBackground)pBalloonCallout;

            //dim and set formatted text symbol for 
            //specialized callout element
            IFormattedTextSymbol pFormattedTextSymbol = (IFormattedTextSymbol)new TextSymbolClass();

            //set label symbol properties
            pFormattedTextSymbol.Background = pTextBackground;
            pFormattedTextSymbol.Size = 12;

            ISimpleTextSymbol pTextSymbol = (ISimpleTextSymbol)pFormattedTextSymbol;
            pTextSymbol.YOffset = 10;
            pTextSymbol.XOffset = 40;
            pTextSymbol.Angle = 45;
            pColor.Blue = 255;
            pColor.Green = 0;
            pColor.Red = 108;
            pTextSymbol.Color = pColor;

            //set text element custom symbol
            pTextElement.Symbol = pTextSymbol;// pFormattedTextSymbol;

            //dim and set element properties object
            IElementProperties pElementPro = (IElementProperties)pTextElement;

            //set element properties
            pElementPro.Type = "Jeffco Callout";

            //dim and set Element to be added to map
            IElement pElement = (IElement)pElementPro;

            //dim and set Geometry
            ESRI.ArcGIS.Geometry.IGeometry pGeometry = (ESRI.ArcGIS.Geometry.IGeometry)pPoint;

            //add graphic to map
            IMap pMap = pMapControl.ActiveView.FocusMap;
            IGraphicsContainer pGraCon = (IGraphicsContainer)pMap;
            pElement.Geometry = pGeometry;

            pGraCon.AddElement(pElement, 0);
            esriViewDrawPhase p = esriViewDrawPhase.esriViewGraphics;
            pMapControl.ActiveView.PartialRefresh(p, pElement, null);
        }
    }
}